<html>
<head>
<script type="text/javascript" src="chrome_ex_oauthsimple.js"></script>
<script type="text/javascript" src="chrome_ex_oauth.js"></script>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false&amp;language=en"></script>
<script type="text/javascript">
Storage.prototype.setObject = function(key, value) {
	this.setItem(key, JSON.stringify(value));
}

Storage.prototype.getObject = function(key) {
	if (this.getItem(key)) {
		return JSON.parse(this.getItem(key));
	}
}

var currentUser;
var geocoder = new google.maps.Geocoder();

var oauth = ChromeExOAuth.initBackgroundPage({
	'request_url': 'https://www.google.com/accounts/OAuthGetRequestToken',
	'authorize_url': 'https://www.google.com/latitude/apps/OAuthAuthorizeToken?domain=www.pommepause.com&location=current&granularity=best',
	'access_url': 'https://www.google.com/accounts/OAuthGetAccessToken',
	'consumer_key': 'www.pommepause.com',
	'consumer_secret': 'xOHGVQZcZGxGPYQ3dqrd0eiv',
	'scope': 'https://www.googleapis.com/auth/latitude https://www.googleapis.com/auth/userinfo#email',
	'app_name': 'Google Latitude for Chrome'
});

oauth.authorize(onAuthorize);

function onAuthorize(token, secret) {
	// Find who authorized us
	var method = 'GET';
	var url = 'https://www.googleapis.com/userinfo/email';
	var params = {'alt': 'json'};
	var xhr = new XMLHttpRequest();
	xhr.onreadystatechange = function(data) {
		if (xhr.readyState == 4 && xhr.status == 200) {
			var data = JSON.parse(xhr.responseText);
			if (typeof data.error != 'undefined' && data.error.code != 500) {
				console.log("Received error " + data.error.code + " (details follows); clearing OAuth tokens.");
				console.log(data.error);
				oauth.clearTokens();
				if (localStorage["ChromeLatitude_token_" + currentUser]) {
					delete localStorage["ChromeLatitude_token_" + currentUser];
					delete localStorage["ChromeLatitude_token_secret_" + currentUser];
				}
			} else if (typeof data.data != 'undefined') {
				currentUser = data.data.email;

				// Store the tokens we received to be able to re-use them later
				localStorage["ChromeLatitude_token_" + currentUser] = oauth.getToken();
				localStorage["ChromeLatitude_token_secret_" + currentUser] = oauth.getTokenSecret();
			}
		}
	};
	xhr.open(method, url + '?alt=json', false);
	xhr.setRequestHeader('GData-Version', '3.0');
	xhr.setRequestHeader('Authorization', oauth.getAuthorizationHeader(url, method, params));
	xhr.send();

	updateCurrentLocation();
}

function getCurrentLocation() {
	getCurrentGoogleUser();
	if (!currentUser) {
		onCurrentLocation('', null);
		return;
	}
	var url = 'https://www.googleapis.com/latitude/v1/currentLocation';
	var request = {
		'method': 'GET',
		'parameters': {'granularity': 'best'}
	};
	oauth.sendSignedRequest(url, onCurrentLocation, request);
}
function onCurrentLocation(resp, xhr) {
	if (resp != '') {
		var data = JSON.parse(resp);
		if (typeof data.error != 'undefined' && data.error.code != 500) {
			console.log("Received error " + data.error.code + " (details follows); clearing OAuth tokens.");
			console.log(data.error);
			oauth.clearTokens();
			if (localStorage["ChromeLatitude_token_" + currentUser]) {
				delete localStorage["ChromeLatitude_token_" + currentUser];
				delete localStorage["ChromeLatitude_token_secret_" + currentUser];
			}
		} else if (typeof data.data != 'undefined') {
			data = data.data;
			if (data.kind == 'latitude#location') {
				if (data.timestampMs) {
					data.lastUpdated = new Date();
					data.lastUpdated.setTime(data.timestampMs);
				}
				localStorage.setObject('currentLocation', data);
				console.log("Last Known Latitude Location: ");
				console.log(localStorage.getObject('currentLocation'));
				return;
			}
		}
	}

	// Display the red icon if there's a problem anywhere
	var icon_details = new Object();
	icon_details.path = 'icon-offline.png';
	chrome.browserAction.setIcon(icon_details);
	oauth.clearTokens();
}

function compareCoords(latLng1, latLng2) {
	if (!latLng1 || !latLng2 || !latLng1.latitude || !latLng2.latitude) {
		return 2;
	}
	if (latLng1.latitude > latLng2.latitude + 0.001) {
		return 1;
	}
	if (latLng1.longitude > latLng2.longitude + 0.001) {
		return 1;
	}
	if (latLng1.latitude < latLng2.latitude - 0.001) {
		return -1;
	}
	if (latLng1.longitude < latLng2.longitude - 0.001) {
		return -1;
	}
	return 0;
}

function updateCurrentLocation(manualCurrentLocation) {
	if (manualCurrentLocation != null) {
		if (!currentUser) {
			alert('You are no longer logged in on google.com. We can\'t update your Latitude location until you log in again.');
			return;
		}

		console.log("Current Location (from manual check-in): ");
		console.log(manualCurrentLocation);

		localStorage.setObject('lastManualLocation', manualCurrentLocation);

		var requestdata = new Object();
		requestdata.data = new Object();
		requestdata.data.latitude = manualCurrentLocation.latitude;
		requestdata.data.longitude = manualCurrentLocation.longitude;

		updateCurrentLatitudeLocation(requestdata);
	} else {
		try {
			getCurrentLocation();
		} catch (err) {
			return err;
		}
		if (!currentUser) {
			return;
		}
		
		// Only update if the Latitude location was last updated more than 30 minutes ago.
		var delay_past = new Date();
		delay_past.setTime(delay_past.getTime() - 1000*60*30);
		
		if (localStorage.getObject('currentLocation') && localStorage.getObject('currentLocation').lastUpdated > delay_past) {
			return;
		}

		navigator.geolocation.getCurrentPosition(function(position) {  
			console.log("Current Location (from browser): ");
			console.log(position);

			// Don't update if the current Latitude location is the same as navigator.geolocation.getCurrentPosition()
			if (compareCoords(position.coords, localStorage.getObject('currentLocation')) == 0) {
				console.log("Skipping Latitude update: current browser location = last known Latitude location");
				// Display the green icon since the Latitude location is OK
				var icon_details = new Object();
				icon_details.path = 'icon.png';
				chrome.browserAction.setIcon(icon_details);
				return;
			}

			var requestdata = new Object();
			requestdata.data = position.coords;
			
			// Don't update if the user did a manual update...
			if (localStorage.getObject('lastManualLocation')) {
				// ... and navigator.geolocation.getCurrentPosition() didn't change...
				if (compareCoords(position.coords, localStorage.getObject('lastBrowserLocation')) == 0) {
					// ... and the current Latitude location is the same as the last manually updated location
					if (compareCoords(localStorage.getObject('lastManualLocation'), localStorage.getObject('currentLocation')) == 0) {
						console.log("Skipping Latitude update: manual check-in location = last known Latitude location");
						// Display the green icon since the Latitude location is OK
						var icon_details = new Object();
						icon_details.path = 'icon.png';
						chrome.browserAction.setIcon(icon_details);
						return;
					} else {
						// current Latitude location is different from the last manual check-in; let's use that instead.
						requestdata.data = lastManualLocation;
					}
				} else {
					// navigator.geolocation.getCurrentPosition() changed; let's use the new value, and remove the saved lastManualLocation.
					delete localStorage['lastManualLocation'];
				}
			}
			localStorage.setObject('lastBrowserLocation', position.coords);

			console.log("Updating Latitude Location to: ");
			console.log(requestdata.data);
			updateCurrentLatitudeLocation(requestdata);
		});
	}
}

function updateCurrentLatitudeLocation(requestdata) {
	getCurrentGoogleUser();
	// Send to Latitude API
	var url = 'https://www.googleapis.com/latitude/v1/currentLocation';
	var request = {
		'method': 'POST',
		'headers': { 'Content-Type': 'application/json' },
	    'body': JSON.stringify(requestdata)
	};
	oauth.sendSignedRequest(url, function(resp, xhr) {
		onCurrentLocation(resp, xhr);
	}, request);
}

chrome.extension.onRequest.addListener(function(request, sender, sendResponse) {
	if (request.method == "getCurrentLocation") {
		getCurrentLocation();
		sendResponse({currentLocation: localStorage.getObject('currentLocation')});
	} else if (request.method == "updateCurrentLocation") {
		var error = updateCurrentLocation(request.latLng);
		sendResponse({currentLocation: localStorage.getObject('currentLocation'), error: error});
	} else if (request.method == "codeAddress") {
		geocoder.geocode( { 'address': request.address }, function(results, status) {
			if (status == google.maps.GeocoderStatus.OK) {
				var latLng = new Object();
				latLng.latitude = results[0].geometry.location.b;
				latLng.longitude = results[0].geometry.location.c;
				sendResponse({latLng: latLng});
			} else {
				alert("Geocode was not successful for the following reason: " + status);
				sendResponse({});
			}
		});
	} else if (request.method == "authorize") {
		oauth.authorize(onAuthorize);
		sendResponse({});
	} else {
		sendResponse({});
	}
});

chrome.tabs.onCreated.addListener(function(tab) {
	updateCurrentLocation();
});

chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
	if (changeInfo.status == 'loading') {
		// changeInfo.url will only be non-empty if the URL changed.
		// This should prevent auto-refreshing pages from triggering location updates!
		if (changeInfo.url != null) {
			updateCurrentLocation();
		}
	}
});

function getCurrentGoogleUser() {
	// Fill currentUser with the currently logged google.com username
	var xhr = new XMLHttpRequest();
	xhr.onreadystatechange = function(data) {
		if (xhr.readyState == 4) {
			currentUser = null;

			if (xhr.status == 200) {
				var re = new RegExp(/<b class="?gb4"?>[\s]*([^<]+@[^<]+)<\/b>/i);
				var m = re.exec(xhr.responseText);
				if (m && m.length == 2) {
					currentUser = m[1];
				}
			}

			console.log("Currently logged user (on google.com): " + currentUser);

			if (!currentUser) {
				var icon_details = new Object();
				icon_details.path = 'icon-offline.png';
				chrome.browserAction.setIcon(icon_details);

				delete localStorage['currentLocation'];
				delete localStorage['lastManualLocation'];
			}

			// We'll only use tokens that we stored ourselves, if any.
			if (localStorage["ChromeLatitude_token_" + currentUser] != null) {
				oauth.clearTokens();
				console.log("Re-using previously stored token: " + localStorage["ChromeLatitude_token_" + currentUser] + ' with secret: ' + localStorage["ChromeLatitude_token_secret_" + currentUser]);
				oauth.setToken(localStorage["ChromeLatitude_token_" + currentUser]);
				oauth.setTokenSecret(localStorage["ChromeLatitude_token_secret_" + currentUser]);
			}
		}
	};
	xhr.open('GET', 'https://www.google.com/', false);
	xhr.send(null);
}
</script>
</head>
<body>
</body>
</html>